import { useLayoutEffect, useRef } from 'react'
import screenfull from 'screenfull'
import useBoolean from '../use-boolean';

export interface Options {
    onExitFull: () => void;
    onFull: () => void;
}

interface Callback {
    setFull: () => void;
    exitFull: () => void;
    toggleFull: () => void;
}

type Value = boolean
type Result = [Value, Callback]

export default (target: HTMLElement, options: Options): Result => {
    const { onExitFull, onFull } = options || {}

    const onExitFullRef = useRef(onExitFull)
    onExitFullRef.current = onExitFull

    const onFullRef = useRef(onFull)
    onFullRef.current = onFull

    const [state, { toggle, setTrue, setFalse }] = useBoolean(false)

    useLayoutEffect(() => {
        if (!state) return

        const el = target
        if (!el) return

        const onChange = () => {
            if (screenfull.isEnabled) {
                const { isFullscreen } = screenfull
                toggle(isFullscreen)
            }
        }

        if (screenfull.isEnabled) {
            try {
                screenfull.request(el)
                setTrue()
                if (onFullRef.current) {
                    onFullRef.current()
                }
            } catch (error) {
                setFalse()
                if (onExitFullRef.current) {
                    onExitFullRef.current()
                }
            }
            screenfull.on('change', onChange)
        }

        return () => {
            if (screenfull.isEnabled) {
                try {
                    screenfull.off('change', onChange)
                    screenfull.exit()
                } catch(error) {}
            }
            if (onExitFullRef.current) {
                onExitFullRef.current()
            }
        }
    }, [state, typeof target === 'function' ? undefined : target])

    const toggleFull = () => toggle()

    return [
        !!state,
        {
            setFull: setTrue,
            exitFull: setFalse,
            toggleFull
        }
    ]
}